home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 45 / Amiga Format CD45 (1999-09)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1999-11].iso / -serious- / misc / mcread / original / mwformat < prev    next >
Text File  |  1999-08-09  |  9KB  |  186 lines

  1. There has been a lot of interest in the format of MacWrite documents,
  2. specifically in terms of the compressed data format for the 3.x and 4.x
  3. test versions which will support disk-based files.  I am hesitant to type
  4. the entire documentation for 3.x and 4.x file formats here and now, but if
  5. there is a sufficient uproar, I may be persuaded to do it.
  6.  
  7. First, a word about MW 2.2.  A MACA/WORD file whose first two bytes
  8. are '00 03' is in 2.2 format.  As we all know, 2.2 reads the entire document
  9. into memory, and you manipulate the document within memory. Here is the RECORD
  10. format for some global variables stored at the beginning of a 2.2 file:
  11.  
  12. MWGlobals = RECORD
  13.         VerNum,          Version number = 3 for MW2.2
  14.         ParaOffset,      Pointer to start of first "paragraph"
  15.         MainPCount,      Number of paragraphs in Main document
  16.         HeadPCount,      Number of paragraphs in Header
  17.         FootPCount:      Number of paragraphs in Footer
  18.                         INTEGER;
  19.  
  20.         TitlePgF,        Title page?
  21.         ScrapDispF,      Display scrap?
  22.         FootDispF,       Display footers?
  23.         HeadDispF,       Display headers?
  24.         RulerDispF,      Display rulers?
  25.         Unused1:         Byte for word alignment
  26.                         BOOLEAN;
  27.  
  28.         AcDocNum,        Document that is currently active:
  29.                                 0 = Main
  30.                                 1 = Header
  31.                                 2 = Footer
  32.         StPgNum:         Starting page number offset
  33.                         INTEGER;
  34. END;  MWGlobals
  35.  
  36. Every MacWrite formatted file has three sections (Main, header, footer) each
  37. comprised of paragraphs. A "paragraph" can be either text, a ruler, or a
  38. picture. The first paragraph is ALWAYS a ruler. So if you are using Fedit,
  39. and you follow the ParaOffset pointer, you will start at a ruler.  The first
  40. two bytes of a paragraph are an integer indicating what kind of paragraph it
  41. is (0=ruler, 1=text, 2=picture).  The next two bytes are an integer indicating
  42. the length of the paragraph.  If you are only interested in text paragraphs,
  43. you can follow ParaOffset to the first paragraph, read the paragraph type
  44. and paragraph length, and skip that many bytes if it is not a text paragraph.
  45. Then read the next paragraph, and so on.  There are MainPCount paragraphs for
  46. the main, followed by HeadPCount paragraphs for the header, followed by
  47. FootPCount paragraphs for the footer.
  48.  
  49. If it is a text paragraph, there would be the two bytes for paragraph type,
  50. two bytes for paragraph length, and then two bytes for the length of the
  51. text.  After the string of text characters, there is a formatting run, the
  52. layout of which is rather grody.
  53.  
  54. Enough for MW2.2 format.  That should be enough to get people started.  I
  55. encourage people to hack around in Fedit to learn more about it.
  56.  
  57. A real sticky wicket, a veritable nasty noodle, is MW 3.x and 4.x file
  58. formats.  They can be identified by a two-byte version number equal to
  59. '00 06'.  The format for the globals at the beginning of the file is similar,
  60. but not identical, to 2.2:
  61.  
  62. MWGlobals = RECORD
  63.         VerNum,          Version number = 6 for MW 3.x and 4.x
  64.         MainPCount,      Number of paragraphs in Main document
  65.         HeadPCount,      Number of paragraphs in Header
  66.         FootPCount:      Number of paragraphs in Footer
  67.                         INTEGER;
  68.  
  69.         TitlePgF,        Title page?
  70.         Unused1:         Byte for word alignment
  71.         ScrapDispF,      Display scrap?
  72.         FootDispF,       Display footers?
  73.         HeadDispF,       Display headers?
  74.         RulerDispF,      Display rulers?
  75.                         BOOLEAN;
  76.  
  77.         AcDocNum,        Document that is currently active:
  78.                                 0 = Main
  79.                                 1 = Header
  80.                                 2 = Footer
  81.         StPgNum:         Starting page number offset
  82.                         INTEGER;
  83. END;  MWGlobals
  84.  
  85. After the starting page number, there is information for using the "free list",
  86. which is how MW 3.x and 4.x manipulate pages on disk and in memory.  It is not
  87. at all necessary to understand the "free list" unless you are writing a
  88. MacWrite clone where you need to be able to swap and edit pages from a
  89. MacWrite-formatted file.  If you only need to be able to read, and perhaps
  90. display, a MacWrite document, you can pretty much avoid the free list stuff
  91. altogether.
  92.  
  93. Reading a paragraph is tricky.  There are "document variables" at positions
  94. 00A0 (footer), 00CE (header), and 00FC (main).  Bytes 12-15 in the document
  95. variables contain the position of the "information array" for the first
  96. paragraph.  (There is an information block for each paragraph in the
  97. header, footer, and main, and each information block is a total of 16 bytes
  98. long.)  The 8th byte in the information block is the status byte
  99. for that paragraph.  Bit number 3 is of special interest, in that
  100. it tells whether the paragraph is in compressed format (to be discussed
  101. shortly).  Bytes 9-11 contain the location of the paragraph data, and bytes
  102. 12-13 are the length of the paragraph data.  To determine what kind of
  103. paragraph it is, bytes 0-1 of the information block contain the paragraph
  104. height.  A positive value indicates the paragraph is text, a negative value
  105. means a picture, and zero indicates a ruler.  Now follow bytes 9-11
  106. to find the paragraph data.  If it is text, the first two bytes of the
  107. paragraph data will be the length of the text in bytes.  It is important to
  108. note that the length is in bytes, not characters, since the characters may be
  109. compressed.
  110.  
  111. ***Text Compression***
  112. This is one of the most interesting things about MW 3.x and 4.x.  In an
  113. attempt to save disk space, Apple came up with a scheme to compress ASCII
  114. text down so that two compressed characters would fit into one byte.  It
  115. works as follows: for any given language (in our case, English), the
  116. developers of the MacWrite system determine the 15 most common characters in
  117. that language.  Note that for almost every language, the most common character
  118. is the space character.  After the space character, it varies from one language
  119. to another, based upon statistical analysis. These 15 characters are then
  120. combined to form a Str255 of length 15.  In the resource fork of the file,
  121. is a resource of type STR (id = 700) which is this string. For the English
  122. language, it looks like this: ' etnroaisdlhcfp'.  Now, when it comes to
  123. compressing text, all you need is one NIBBLE to represent one of these 15
  124. characters.  The nibbles that are used are 0-E.  The nibble F is used to
  125. indicate that the two nibbles that follow are NOT compressed characters, but
  126. comprise a complete ASCII character.  So for example, the word 'tent' would
  127. look like '21 32', and the word 'Tent' would look like 'F5 41 32'.  The
  128. string 'The tent' would look like 'F5 4B 10 21 32'.  Notice immediately that
  129. we gain a nibble for each compressed character, but we lose one for each
  130. non-compressed character.  In the long run, this technique wins bytes.  If,
  131. however, the text was pathologically bizarre, and it had lots of capital
  132. letters and punctuation and infrequent letters, then we would be wasting space
  133. to use up an extra nibble on each uncompressible character.  That is why there
  134. is a compressed bit.  The MacWrite program determines whether it will win
  135. anything by using this compression technique, and acts accordingly.
  136.  
  137. Let's try running through how we can read out the text of the main part of
  138. a MacWrite document:
  139.  
  140. 1) Verify version number = 6
  141.  
  142. 2) MainPCount = bytes 0002-0003
  143.  
  144. 3) M_IAP = bytes 0108-010B  Main Info Array Pointer
  145.    The byte positions are calculated from the Main Document Variable
  146.    offset of 00FC, plus the offsets of 12D-15D into the MainDocVars.
  147.  
  148. 4) Paratype = bytes (M_IAP) - (M_IAP+1)
  149.  
  150. 5) psb = byte (M_IAP+8)  Paragraph Status Byte
  151.  
  152. 6) CompBit = bit 3 of psb  Compression Bit
  153.  
  154. 7) pdp = bytes (M_IAP+9) - (M_IAP+11)  Paragraph Data Pointer
  155.  
  156. 8) para_len = bytes (M_IAP+12) - (M_IAP+13)  Paragraph length
  157.  
  158. Now, if Paratype is positive, we go to the paragraph itself...
  159.  
  160. 9) text_len = bytes (pdp) - (pdp+1)
  161.  
  162. 10) proceed to read text_len number of bytes, and decompress using the
  163.     scheme described above (if compressed bit is set)
  164.  
  165.  
  166. The information described above is excerpted from documentation furnished by:
  167. Encore Systems
  168. 20823 Stevens Creek Blvd. C1-B
  169. Cupertino, California  95014
  170. (408)446-9565
  171.  
  172. We can vouch for the above description, since we are currently involved with
  173. developing software which will interact with MacWrite files.  If you have
  174. any questions about details of MacWrite file format, or about our project here
  175. at Cornell, write or call us.  We may respond individually, or via the net.
  176.  
  177. Kate MacGregor and Douglas Young
  178. Decentralized Computer Services
  179. 401 Uris Hall
  180. Cornell University
  181. Ithaca, NY  14853
  182. (607)256-4981
  183.  
  184. Doug Young's electronic address is DMYJARTJ@CORNELLA.BITNET
  185. -------
  186.